package com.xsjiong.iamath.android;

import android.content.*;
import android.graphics.*;
import android.util.*;
import android.view.*;
import com.xsjiong.exgraph.*;
import android.graphics.drawable.*;

public class AndroidGraphView extends SurfaceView implements SurfaceHolder.Callback {
	private SurfaceHolder H;
	private ExCanvas E;
	private Runnable RefreshRunnable;
	private Paint P;
	public AndroidGraphView(Context cx) {
		this(cx, null, 0);
	}
	public AndroidGraphView(Context cx, AttributeSet attr) {
		this(cx, attr, 0);
	}
	public AndroidGraphView(Context cx, AttributeSet attr, int style) {
		super(cx, attr, style);
		Initialize();
	}
	public void setExCanvas(ExCanvas c) {
		if (E != null) E.RefreshRunnable = null;
		this.E = c;
		E.RefreshRunnable = RefreshRunnable;
	}
	public ExCanvas getExCanvas() {
		return this.E;
	}
	private void Initialize() {
		H = getHolder();
		H.addCallback(this);
		setFocusable(true);
		setFocusableInTouchMode(true);
		this.P = new Paint();
		//P.setAntiAlias(true);
		P.setStyle(Paint.Style.STROKE);
		P.setTextSize(20);
		RefreshRunnable = new Runnable() {
			@Override
			public void run() {
				try {
					long st = System.currentTimeMillis();
					C = H.lockCanvas();
					C.drawColor(Color.WHITE);
					E.draw(new CanvasPainter(C, P));
					st = System.currentTimeMillis() - st;
					C.drawText(Long.toString(st), 0, 0, P);
					H.unlockCanvasAndPost(C);
				} catch (Throwable t) {
					t.printStackTrace();
					if (C != null) H.unlockCanvasAndPost(C);
				}
			}
		};
	}

	private boolean Running = false;

	@Override
	public void surfaceCreated(SurfaceHolder a) {
		Running = true;
		E.Refresh();
	}

	@Override
	public void surfaceChanged(SurfaceHolder a, int format, int width, int height) {}

	@Override
	public void surfaceDestroyed(SurfaceHolder p1) {
		Running = false;
	}

	private Canvas C;

	public static class CanvasPainter implements Painter {
		private Canvas C;
		private Paint P;
		public CanvasPainter(Canvas c, Paint p) {
			this.C = c;
			this.P = p;
		}
		@Override
		public void setColor(int r, int g, int b) {
			P.setColor(Color.rgb(r, g, b));
		}

		@Override
		public void setFillMode(boolean fill) {
			P.setStyle(fill ?Paint.Style.FILL: Paint.Style.STROKE);
		}

		@Override
		public void drawRect(float x, float y, float width, float height) {
			C.drawRect(x, y, width, height, P);
		}

		@Override
		public void drawPoint(float x, float y) {
			if (DrawingFunction) {
				if (CX == -1)
					C.drawPoint(CX = x, CY = y, P);
				else C.drawLine(CX, CY, CX = x, CY = y, P);
			} else C.drawPoint(x, y, P);
		}

		@Override
		public void drawCircle(float x, float y, float radius) {
			C.drawCircle(x, y, radius, P);
		}

		@Override
		public int getWidth() {
			return C.getWidth();
		}

		@Override
		public int getHeight() {
			return C.getHeight();
		}
		private boolean DrawingFunction = false;
		private float CX,CY;

		@Override
		public void BeginFunction() {
			DrawingFunction = true;
			CX = -1;
			CY = -1;
		}

		@Override
		public void EndFunction() {
			DrawingFunction = false;
		}

		@Override
		public void drawLine(float x1, float y1, float x2, float y2) {
			C.drawLine(x1, y1, x2, y2, P);
		}
	}
}
